#include <stdio.h>
#include <string.h>
#include <malloc.h>

/* we want assertion failures in these tests */
#undef NDEBUG
#define DEBUG

#include <assert.h>

#include "hashtable.h"

static unsigned long hashword(void * word)
{
  return hashtable_djb2((unsigned char *) word, 0);
}

static int cmpword(void * word1, void * word2)
{
  return strcmp((const char *) word1, (const char *) word2);
}

int main(int argc, char ** argv)
{
  void * table;
  void * iter;
  void * record;
  
  int i;
  char * buf;
 
  printf("INITIAL MEMORY STATS:\n");
  malloc_stats();

  table = hashtable_alloc(10, 2, hashword, cmpword);
  
  for (i=0; i<30; i++)
  {
    buf = (char *)malloc(20);
    sprintf(buf, "%d", i);
    assert(!hashtable_insert(table, (void *) buf));
  }

  assert(NULL != hashtable_find(table, "29"));
  assert(NULL == hashtable_find(table, "30"));

  for(iter = hashtable_itr_start(table); (record = hashtable_itr_next(iter)); )
    printf("%s ", (char *) record);
  printf("\n");
  hashtable_itr_end(iter);
  
  for (i=0; i<30; i++)
  {
    char buf[20];
    void * record;
    sprintf(buf, "%d", i);
    record = hashtable_find(table, (void *) buf);
    assert(NULL != record);
    assert(record != buf);
    assert(!strcmp((const char *)record, (const char *) buf));
    
    record = hashtable_delete(table, (void *) buf);
    assert(NULL != record);
    assert(record != buf);
    assert(!strcmp((const char *)record, (const char *) buf));
    free(record);
  }

  assert(NULL == hashtable_find(table, "11"));

  hashtable_free(table);

  printf("FINAL MEMORY STATS:\n");
  malloc_stats();
  return 0;
}
